package org.sd.netty;

import javax.servlet.ServletException;

import io.netty.handler.codec.http.HttpContentCompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;


public class DispatcherServletChannelInitializer extends ChannelInitializer<SocketChannel> {

	private final DispatcherServlet dispatcherServlet;

    public DispatcherServletChannelInitializer() throws ServletException {

    	//MockServletContext servletContext = new MockServletContext();

        MockServletContext servletContext = new CustomMockServletContext();
        MockServletConfig servletConfig = new MockServletConfig(servletContext);

        XmlWebApplicationContext context = new XmlWebApplicationContext();
        context.setServletContext(servletContext);
        context.setServletConfig(servletConfig);

        //XmlWebApplicationContext mvcContext = new XmlWebApplicationContext();
    	//MockServletConfig servletConfig = new MockServletConfig(mvcContext.getServletContext(), "dispatcherServlet");
        //servletConfig.addInitParameter("contextConfigLocation","classpath:/META-INF/spring/root-context.xml");
        //servletContext.addInitParameter("contextConfigLocation","classpath:/META-INF/spring/root-context.xml");

    	//AnnotationConfigWebApplicationContext wac = new AnnotationConfigWebApplicationContext();


        //ClassPathXmlApplicationContext wac = new ClassPathXmlApplicationContext();
		//wac.setServletContext(servletContext);
        //mvcContext.setServletConfig(servletConfig);
        context.setConfigLocation("classpath:/servlet-context.xml");
    	//wac.register(WebMvcConfig.class);

        // 初始化WebApplicationContext
        context.refresh();

    	dispatcherServlet = new DispatcherServlet(context);
    	this.dispatcherServlet.init(servletConfig);
	}

    @Override
    public void initChannel(SocketChannel channel) throws Exception {
        // Create a default pipeline implementation.
        ChannelPipeline pipeline = channel.pipeline();

        // Uncomment the following line if you want HTTPS
        //SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
        //engine.setUseClientMode(false);
        //pipeline.addLast("ssl", new SslHandler(engine));

        //pipeline.addLast("decoder", new HttpRequestDecoder());
        //pipeline.addLast("encoder", new HttpResponseEncoder());
        //pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
        //pipeline.addLast("handler", new ServletNettyHandler(this.dispatcherServlet));

        // TODO Auto-generated method stub
        //ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast("decoder", new HttpRequestDecoder());
        pipeline.addLast("encoder", new HttpResponseEncoder());
        pipeline.addLast("aggregator", new HttpObjectAggregator(2147483647));
        pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
        pipeline.addLast("deflater", new HttpContentCompressor());
        pipeline.addLast("handler", new HttpRequestHandler(this.dispatcherServlet));
    }


    /*@Configuration
    @EnableWebMvc
    @ComponentScan(basePackages="org.springframework.sandbox.mvc")
    static class WebConfig extends WebMvcConfigurerAdapter {
    }*/

    @Configuration
    public class WebMvcConfig extends WebMvcConfigurationSupport {

        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            //将templates目录下的CSS、JS文件映射为静态资源，防止Spring把这些资源识别成thymeleaf模版
            registry.addResourceHandler("/templates/**.js").addResourceLocations("classpath:/templates/");
            registry.addResourceHandler("/templates/**.css").addResourceLocations("classpath:/templates/");
            //其他静态资源
            registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        }
    }

}
